#pragma once

#include "Singleton.h"
#include "Loot/CreatureLooterMgr.h"

class PlayBossMgr : public WheelTwinklerOwner, public Singleton<PlayBossMgr>
{
public:
	PlayBossMgr();
	virtual ~PlayBossMgr();

	void Init();

	GErrorCode HandlePlayerJoin(ObjGUID playerGuid);
	GErrorCode HandlePlayerChangeTeam(
		ObjGUID playerGuid, const ClientAddr4Cross& clientAddr,
		uint32 teamId, const std::string_view& teamName);
	GErrorCode HandlePlayerStrike(
		InstGUID instGuid, const ClientAddr4Cross& clientAddr,
		ObjGUID playerGuid, const std::string_view& playerName,
		uint32 teamId, const std::string_view& teamName,
		uint32 spawnId, uint64 loseHP);
	GErrorCode HandleInstanceSync(
		InstGUID instGuid, PlayBossSyncType syncType, INetPacket& pck);
	GErrorCode HandleBroadcast(INetPacket& pck);

private:
	void StartPlay(const TriggerPoint& triggerPoint, time_t actvtTime);
	void StopPlay();

	void SendRank2Client(
		ObjGUID playerGuid, const ClientAddr4Cross& clientAddr) const;

	void SendPacket2AllInstance(
		const INetPacket& pck, InstGUID exceptInstGuid = InstGUID_NULL) const;

	bool IsAllBossDead() const;

	virtual WheelTimerMgr *GetWheelTimerMgr();

	enum class ActvtStatus {
		None,
		Initing,
		Playing,
	};
	struct InstanceStatus {
		uint32 playerNum = 0;
	};
	struct BossStatus {
		uint32 level = 0;
		uint64 lossHPVal = 0;
		uint64 totalHPVal = 0;
	};
	ActvtStatus m_actvtStatus;
	uint32 m_instSeed;
	std::map<InstGUID, InstanceStatus> m_allInstanceStatus;
	std::map<uint32, BossStatus> m_allBossStatus;
	TeamRankLooterMgr m_looterMgr;
	time_t m_startTime, m_actvtTime;
};

#define sPlayBossMgr (*PlayBossMgr::instance())
